require 'rubygems'
require 'gosu'
require 'chipmunk'



SCREEN_WIDTH, SCREEN_HEIGHT = 448, 512


#DTIME is basically how long each substep
# is.  Lower values will increates the accuracy while higher help performance.
SUBSTEPS, DTIME = 3, (1.0 / 30.0)

class Barrel
  attr_reader :body, :shape
  
  def initialize(space, image)
    @body  = CP::Body.new(1.0, 1.0)
    @shape = CP::Shape::Circle.new(@body, 22.0/2, CP::Vec2.new(0,0))
    @image = image
        
    @shape.body.p = CP::Vec2.new(168, 140)      # position     
    @shape.e = 0.5 #elasticity
    @shape.u = 0.1 #friction
    @shape.collision_type=:barrel    
    @shape.body.apply_impulse(CP::Vec2.new(10.0, 0.0), CP::Vec2.new(0.1, 0))
    space.add_body(@body)
    space.add_shape(@shape)
  end
  

  def draw
    @image.draw_rot(@shape.body.p.x, @shape.body.p.y, 1, @shape.body.a.radians_to_gosu, 0.5, 0.5, 1, 1)    
  end
end

class GameWindow < Gosu::Window
  
  def initialize
    super(SCREEN_WIDTH, SCREEN_HEIGHT, false)
    setup_scene
  end

  def draw_structure(x_from,y_from,x_to,y_to,group)
    sp=CP::Shape::Segment.new(@static_body, CP::Vec2.new(x_from,   y_from), CP::Vec2.new(x_to, y_to), 1.0)
    sp.e = 0.9 #elasticity
    sp.u = 0.1 #friction
    sp.collision_type=group
    @space.add_shape sp
  end
  
  def setup_scene
    @beep = Gosu::Sample.new(self, "#{File.dirname(__FILE__)}/sound/Beep.wav")
    @bg_image = Gosu::Image.new(self, "#{File.dirname(__FILE__)}/graphics/donkey_kong_small.png", true)
    @box_image = Gosu::Image.new(self, "#{File.dirname(__FILE__)}/graphics/donkey_kong_small_barrel.png", true)
    
    # Collection of Barrels
    @barrels = Array.new
    
    # Create our Space with a bit of resistance and simple gravity.
    @space = CP::Space.new
    @space.damping = 1#0.8
    @space.gravity = CP::Vec2.new(0.0, 40.0)
    @space.elastic_iterations=3    
    
    @static_body = CP::Body.new((1.0 / 0.0), (1.0 / 0.0));
    
    # borders        
    draw_structure( 0.0,   0.0, 0.0, 400.0, :wall)
    draw_structure( 448.0,   0.0, 448.0, 512.0, :wall)
    draw_structure( 0.0,   512.0, 448.0, 512.0, :wall)
    
     #5th floor
    draw_structure( 0.0,   168.0, 287.0, 168.0, :floor)
    draw_structure( 288.0,   170.0, 414.0, 176.0, :floor)
    
    #4th floor
    draw_structure( 448.0,   219.0, 31.0, 244.0, :floor)
    
    #3th floor
    draw_structure( 0.0,   285.0, 414.0, 309.0, :floor)
    
    #2th floor
    draw_structure( 448.0,   349.0, 31.0, 374.0, :floor)    
    
    #1th floor
    draw_structure( 0.0,   416.0, 414.0, 442.0, :floor)
    
    #ground floor
    draw_structure( 448.0,   482.0, 225.0, 496.0, :floor)
    draw_structure( 255.0,   498.0, 0.0, 498.0, :floor)
    
    
   @space.add_collision_func(:barrel, :wall) do |barrel_shape, floor_shape|      
      @beep.play      
    end

  end
 
  def add_barrel
    box = Barrel.new(@space, @box_image)
    @barrels.push box
  end

  
  def update
    # Perform the physics steps first
    SUBSTEPS.times do
      @space.step(DTIME)
    end
    
  @space.gravity = CP::Vec2.new(0.0, 50.0)  if button_down? Gosu::Button::KbUp
  @space.gravity = CP::Vec2.new(0.0, 0.1)  if button_down? Gosu::Button::KbDown   
  end
  
  def draw
    @bg_image.draw(0,0,0)
    @barrels.each { |box| box.draw }
  end
  
  def button_down(id)
    if id == Gosu::Button::KbEscape
      close
    elsif id == Gosu::Button::KbSpace
      add_barrel
    end 
  end
end

window = GameWindow.new
window.show
